# -*- coding: utf-8 -*-
# @Time    : 2024/7/18 17:32
# @Author  : yujiahao
# @File    : 42_fastapi_routers_users.py
# @description:APIRouter

"""
更大的应用 - 多个文件:

1. 如果你正在开发一个应用程序或 Web API，很少会将所有的内容都放在一个文件中。
   FastAPI 提供了一个方便的工具，可以在保持所有灵活性的同时构建你的应用程序。
   - 如果你来自 Flask，那这将相当于 Flask 的 Blueprints。

2. 一个文件结构示例:
   .
   ├── app
   │   ├── __init__.py
   │   ├── main.py
   │   ├── dependencies.py
   │   └── routers
   │   │   ├── __init__.py
   │   │   ├── items.py
   │   │   └── users.py
   │   └── internal
   │       ├── __init__.py
   │       └── admin.py

3. 目录说明:
   - app 目录包含了所有内容，并且它有一个空文件 app/__init__.py，因此它是一个「Python 包」（「Python 模块」的集合）：app。
   - 它包含一个 app/main.py 文件。由于它位于一个 Python 包（一个包含 __init__.py 文件的目录）中，因此它是该包的一个「模块」：app.main。
   - 还有一个 app/dependencies.py 文件，就像 app/main.py 一样，它是一个「模块」：app.dependencies。
   - 有一个子目录 app/routers/ 包含另一个 __init__.py 文件，因此它是一个「Python 子包」：app.routers。
   - 文件 app/routers/items.py 位于 app/routers/ 包中，因此它是一个子模块：app.routers.items。
   - 同样适用于 app/routers/users.py，它是另一个子模块：app.routers.users。
   - 还有一个子目录 app/internal/ 包含另一个 __init__.py 文件，因此它是又一个「Python 子包」：app.internal。
   - app/internal/admin.py 是另一个子模块：app.internal.admin。

4. 带有注释的同一文件结构:
   .
   ├── app                  # 「app」是一个 Python 包
   │   ├── __init__.py      # 这个文件使「app」成为一个 Python 包
   │   ├── main.py          # 「main」模块，例如 import app.main
   │   ├── dependencies.py  # 「dependencies」模块，例如 import app.dependencies
   │   └── routers          # 「routers」是一个「Python 子包」
   │   │   ├── __init__.py  # 使「routers」成为一个「Python 子包」
   │   │   ├── items.py     # 「items」子模块，例如 import app.routers.items
   │   │   └── users.py     # 「users」子模块，例如 import app.routers.users
   │   └── internal         # 「internal」是一个「Python 子包」
   │       ├── __init__.py  # 使「internal」成为一个「Python 子包」
   │       └── admin.py     # 「admin」子模块，例如 import app.internal.admin

5. 使用 APIRouter:
   - 假设专门用于处理用户逻辑的文件是位于 /app/routers/users.py 的子模块。
   - 你希望将与用户相关的路径操作与其他代码分开，以使其井井有条。
   - 但它仍然是同一 FastAPI 应用程序/web API 的一部分（它是同一「Python 包」的一部分）。
   - 你可以使用 APIRouter 为该模块创建路径操作。

APIRouter 的核心作用:

1. 提取和复用公共路径参数:
   - APIRouter 允许你在一个模块中定义和复用公共的路径和参数，从而减少重复代码。
   - 例如，你可以在一个模块中定义所有与用户相关的路由，并为这些路由设置一个公共的前缀 /users。

2. 管理大型项目中的路由:
   - APIRouter 使你可以将大型项目的路由分解成多个独立的模块，每个模块负责不同的功能或资源。
   - 这不仅使代码更清晰、更易于管理，还便于团队协作和代码维护。

本案例是共有三个同级模块说明一下
          my_fastapi
          ├── 42_fastapi_routers_users.py
          ├── 43_fastapi_routers_items.py
          ├── 44_fastapi_routers_main.py
          ├── __init__.py


"""

"""
这个文件定义了与用户相关的路由和操作。
主要功能包括：
1. 创建用户：允许客户端通过 POST 请求创建一个新用户。
2. 获取用户列表：允许客户端通过 GET 请求获取用户列表，可以通过查询参数指定跳过的记录数和返回的记录数。
3. 获取单个用户：允许客户端通过 GET 请求获取指定 ID 的用户信息。
"""

from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
from typing import List


# 定义 Pydantic 模型
class User(BaseModel):
    """
    用户模型，用于表示用户数据。
    """
    id: int
    email: str
    is_active: bool


class UserCreate(BaseModel):
    """
    用户创建模型，用于接收创建用户的请求数据。
    """
    email: str
    password: str


# 创建 APIRouter 实例
router = APIRouter()

# 用于存储用户数据的内存数据结构
fake_users_db = []


# 创建用户的路由
@router.post("/", response_model=User)
def create_user(user: UserCreate):
    """
    创建一个新的用户。
    - **user**: 用户创建模型
    """
    new_user = User(id=len(fake_users_db) + 1, email=user.email, is_active=True)
    fake_users_db.append(new_user)
    return new_user


# 获取用户列表的路由
@router.get("/", response_model=List[User])
def read_users(skip: int = 0, limit: int = 10):
    """
    获取用户列表。
    - **skip**: 跳过的记录数量
    - **limit**: 返回的记录数量
    """
    return fake_users_db[skip: skip + limit]


# 获取单个用户的路由
@router.get("/{user_id}", response_model=User)
def read_user(user_id: int):
    """
    获取单个用户信息。
    - **user_id**: 用户ID
    """
    for user in fake_users_db:
        if user.id == user_id:
            return user
    raise HTTPException(status_code=404, detail="User not found")
